package com.wyl.netty.common.execute;

import com.wyl.netty.common.protobuf.MessageModule;
import com.wyl.netty.common.protobuf.MessageModule.ResultType;
import com.wyl.netty.common.scanner.Invoker;
import com.wyl.netty.common.scanner.InvokerTable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil;

/**
 * @author: wyl
 * @date: 2021/7/13
 * @des: 响应数据封装
 */
public class MessageTask4Response implements Runnable {

    private MessageModule.Message message;
    private ChannelHandlerContext ctx;

    public MessageTask4Response(MessageModule.Message message, ChannelHandlerContext ctx) {
        this.message = message;
        this.ctx = ctx;
    }

    @Override
    public void run() {
        try {
            //	user-return
            String module = this.message.getModule();
            //	save-return
            String cmd = this.message.getCmd();
            //	响应的结果
            ResultType resultType = this.message.getResultType();
            //	响应的内容
            byte[] data = this.message.getBody().toByteArray();

            Invoker invoker = InvokerTable.getInvoker(module, cmd);
            invoker.invoke(resultType, data);

        } finally {
            /* ==============很重要==============
            client端的Buffer为何要手动释放资源，而server端的则不用？
            使用http请求时使用的 SimpleChannelInboundHandler，则不需要手动关闭资源
            ChannelInboundHandlerAdapter
            SimpleChannelInboundHandler 是上面的子类
            两个的区别
            ChannelInboundHandlerAdapter 不会对资源进行回收
            SimpleChannelInboundHandler 会对资源进行回收

            总结，若使用线程池，由于SimpleChannelInboundHandler 会对资源释放，所以只能使用ChannelInboundHandlerAdapter
            但是ChannelInboundHandlerAdapter 不会对资源进行释放，所以最后客户端要手动释放

            由于服务端调用的是writeAndFlush，会自动给释放，而客户端接收响应后无需返回消息给服务器，所以必须手动释放

            若同步，不使用线程池时，客户端使用SimpleChannelInboundHandler即可
            */
            ReferenceCountUtil.release(message);
        }
    }
}
